var Feed;

(function () {
    var instance;
    
    Feed = function () {
        var get, getDataProcessor, isFeedReady, getErrorProcessor,
                settings, background;
        
        if (instance) {
            return instance;
        }
        instance = this;
        
        get = new Get();
        settings = new Settings();
        background = chrome.extension.getBackgroundPage();
        background = new background.Background();
        
        this.loadFeed = function (subscriptions, callback, errorCallback) {
            var i, feed, url;
            feed = {};
            for (i = subscriptions.length; i--;) {
                feed[subscriptions[i]] = null;
            }
            background.resetFeedLoadingProgress();
            background.initFeedLoadingProgress(subscriptions);
            for (i = subscriptions.length; i--;) {
                url = 'https://gdata.youtube.com/feeds/api/users/' +
                        subscriptions[i] +
                        '/uploads?v=2&alt=jsonc&max-results=25';
                get.get(url, getDataProcessor(feed, subscriptions,
                        subscriptions[i], callback), getErrorProcessor(feed,
                        subscriptions, subscriptions[i], callback,
                        errorCallback));
            }
        };
        
        getErrorProcessor = function (feed, subscriptions, current, callback,
                errorCallback) {
            return function (xhr) {
                if (xhr.status == 403) {
                    feed[current] = [];
                    if (isFeedReady(feed, subscriptions)) {
                        callback(feed);
                    }
                }
                errorCallback(xhr);
            }
        };
        
        getDataProcessor = function (feed, subscriptions, current, callback) {
            return function (text) {
                var data, i, leastDate, leastMonth, leastDay;
                background.setFeedLoadingProgress(current, true);
                feed[current] = [];
                data = JSON.parse(text);
                data = (data && data.data && data.data.items) ?
                        data.data.items : [];
                if (settings.getIgnore()) {
                    leastDate = new Date((new Date()).getTime() -
                            settings.getIgnore() * 1000);
                    leastMonth = (leastDate.getMonth() + 1).toString();
                    leastDay = leastDate.getDate().toString();
                    leastDate = leastDate.getFullYear() + '-' +
                            (leastMonth.length > 1 ? leastMonth : '0' +
                            leastMonth) + '-' + (leastDay.length > 1 ?
                            leastDay : '0' + leastDay);
                } else {
                    leastDate = '';
                }
                for (i = data.length; i--;) {
                    if (leastDate < data[i].uploaded) {
                        feed[current].push({
                            id: data[i].id,
                            uploaded: data[i].uploaded,
                            uploader: current,
                            title: data[i].title,
                            description: data[i].description,
                            duration: data[i].duration,
                            views: data[i].viewCount
                        });
                    }
                }
                feed[current].sort(function (vid1, vid2) {
                    return vid1.uploaded > vid2.uploaded ? 1 : -1;
                });
                if (isFeedReady(feed, subscriptions)) {
                    callback(feed);
                }
            };
        };
        
        isFeedReady = function (feed, subscriptions) {
            var i;
            for (i = subscriptions.length; i--;) {
                if (!(feed[subscriptions[i]] instanceof Array)) {
                    return false;
                }
            }
            return true;
        };
        
        return instance;
    };
}());
